package clang.functions;

import java.util.Vector;

import clang.control.CodeBlock;
import clang.control.CodeElement;
import clang.control.ExecutionThread;
import clang.data.Expression;
import clang.data.VarType;
import clang.data.Variable;

public class Function {
	private FunctionSignature sig;
	private CodeBlock block;
	private int uid = -1;
	
	public Function(String name)
	{
		sig = new FunctionSignature(null, VarType.VOID, name, false);
		block = new CodeBlock(ExecutionThread.get().getRootBlock());
	}
	
	public Function(String name, int uid)
	{
		sig = new FunctionSignature(null, VarType.VOID, name, false);
		block = new CodeBlock(ExecutionThread.get().getRootBlock());
		this.uid = uid;
	}
	
	public Function(FunctionSignature sig, int uid)
	{
		this.sig = sig;
		block = new CodeBlock(ExecutionThread.get().getRootBlock());
		this.uid = uid;
	}
	
	public void append(CodeElement el)
	{
		block.append(el);
	}
	
	public void setBlock(CodeBlock cb)
	{
		block = cb;
	}
	
	public CodeBlock getBlock() {
		return block;
	}
	
	public void setSignature(FunctionSignature sig)
	{
		this.sig = sig;
	}
	
	public void setReturnType(VarType t)
	{
		this.sig.setReturnType(t);
	}
	
	public Variable execute(Vector<Expression> params) throws Exception
	{
		if(uid >= 0)
			return StdLib.get().execFunction(uid, params);
		else
		{
			Vector<Variable> transParams = new Vector<Variable>();
			for(int i = 0; i < params.size(); ++i)
				transParams.add(new Variable(params.get(i).calculate(), sig.parNames.get(i)));
			return block.execute(transParams);
		}
	}
	
	public FunctionSignature getSignature()
	{
		return sig;
	}
}
